package com.tianji.learning.task;

import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.DateUtils;
import com.tianji.learning.constants.RedisConstants;
import com.tianji.learning.domain.po.PointsBoard;
import com.tianji.learning.domain.po.PointsBoardSeason;
import com.tianji.learning.service.IPointsBoardSeasonService;
import com.tianji.learning.service.IPointsBoardService;
import com.tianji.learning.utils.TableInfoContext;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Component
@Slf4j
@RequiredArgsConstructor
public class PointsBoardPersistentHandler {
    private final IPointsBoardSeasonService pointsBoardSeasonService;
    private final IPointsBoardService pointsBoardService;
    private final StringRedisTemplate redisTemplate;
    /**
     * 创建上赛季的表
     */
    //@Scheduled(cron = "0 0 3 1 * ?")
    @XxlJob("createTableJob")
    public void createPointsBoardTableOfLastSeason(){
        System.out.println("创建执行任务");
        //上个月的时间
        LocalDate now = LocalDate.now();
        LocalDate date = now.minusMonths(1);
        //时间对应的赛季信息
        PointsBoardSeason season = pointsBoardSeasonService.lambdaQuery()
                .le(PointsBoardSeason::getBeginTime, date)
                .ge(PointsBoardSeason::getEndTime, date)
                .one();
        if (season==null){
            return;
        }
        System.out.println("执行建表语句:{}");
        //建表
        pointsBoardSeasonService.createPointsBoardTableBySeason(season.getId());
    }
    /**
     * 持久化redis数据到mysql
     */
    @XxlJob("savePointsBoard2DB")
    public void savePointsBoard2DB(){
        //1.获取上个月的赛季信息
        //上个月的时间
        LocalDate now = LocalDate.now();
        LocalDate date = now.minusMonths(1);
        //时间对应的赛季信息
        PointsBoardSeason season = pointsBoardSeasonService.lambdaQuery()
                .le(PointsBoardSeason::getBeginTime, date)
                .ge(PointsBoardSeason::getEndTime, date)
                .one();
        if (season==null){
            return;
        }
        //拼接key
        String format = date.format(DateTimeFormatter.ofPattern("yyyyMM"));
        String key = RedisConstants.POINTS_BOARD_KEY_PREFIX + format;
        //2.分页查询榜单数据

        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();
        int pageNo = shardIndex+1;
        int pageSize = 5;
        while(true){
            List<PointsBoard> boards = pointsBoardService.queryCurrentBoard(key, pageNo, pageSize);
            if (CollUtils.isEmpty(boards)){
                break;
            }
            for (PointsBoard board : boards) {
                board.setId(board.getRank().longValue());
                board.setRank(null);
            }
            //3.计算动态表名
            TableInfoContext.setInfo("points_board_"+season.getId());
            //4.持久化到db
            pointsBoardService.saveBatch(boards);
            pageNo+=shardTotal;
        }
        //5.清除ThreadLocal中的表名
        TableInfoContext.remove();
    }
    @XxlJob("clearPointsBoardFromRedis")
    public void clearPointsBoardFromRedis(){
        // 1.获取上月时间
        LocalDateTime time = LocalDateTime.now().minusMonths(1);
        // 2.计算key
        String format = time.format(DateTimeFormatter.ofPattern("yyyyMM"));
        String key = RedisConstants.POINTS_BOARD_KEY_PREFIX + format;
        // 3.删除
        redisTemplate.unlink(key);
    }
}
